#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include "Jeu.h"
#include "Visiteur.h"




void jeuInit(jeu * laby,vecteur * position,char pied,char regard,int n)
{
  /* Allocation esp et joueur */
  
  laby->esp=(espace*)malloc(sizeof(espace));
  laby->joueur=(visiteur*)malloc(sizeof(visiteur));
  InitEspace(laby->esp,n);
  visiteurInit(laby->joueur,position,pied,regard,n);
}
void jeuInitAlea(jeu * laby,int n)
{
  char direction;
  int i,j=6,bool=1;
  vecteur v1={1,0,0},v2={0,1,0},v3={0,0,1},v4={-1,0,0},v5={0,-1,0},v6={0,0,-1};
  vecteur pied,position,regard,axe,fin;
  vecteur *tab=(vecteur *)malloc(6*sizeof(vecteur));
  vecteur *tabx=(vecteur *)malloc(4*sizeof(vecteur));
  vecteur *taby=(vecteur *)malloc(4*sizeof(vecteur));
  vecteur *tabz=(vecteur *)malloc(4*sizeof(vecteur));
  
  laby->esp=(espace*)malloc(sizeof(espace));
  laby->joueur=(visiteur*)malloc(sizeof(visiteur));
  initEspaceAlea(laby->esp,&pied,&fin, n);

  /* Remplissage du tableau tab des voisins directs(partageant une face) de la case pied */
  addition(&pied, &v1,&tab[0],n);

  addition(&pied, &v2,&tab[1],n);

  addition(&pied, &v3,&tab[2],n);

  addition(&pied, &v4,&tab[3],n);
  
  addition(&pied, &v5,&tab[4],n);

  addition(&pied, &v6,&tab[5],n);

  /* Remplissage du tableau tabx des 4 vecteurs unitaires du plan (z,y) */
  remplaceVecteur(&tabx[0], &v2);
  remplaceVecteur(&tabx[1], &v3);
  remplaceVecteur(&tabx[2], &v5);
  remplaceVecteur(&tabx[3], &v6);

  /* Remplissage du tableau taby des 4 vecteurs unitaires du plan (x,z) */
  remplaceVecteur(&taby[0], &v1);
  remplaceVecteur(&taby[1], &v3);
  remplaceVecteur(&taby[2], &v4);
  remplaceVecteur(&taby[3], &v6);
 
  /* Remplissage du tableau tabz des 4 vecteurs unitaires du plan (x,y) */
  remplaceVecteur(&tabz[0], &v1);
  remplaceVecteur(&tabz[1], &v2);
  remplaceVecteur(&tabz[2], &v4);
  remplaceVecteur(&tabz[3], &v5);

  /* Fin des remplissages */
 

  /* On tire maintenant un entier au hasard entre 0 et 5 puis on teste si la case correspondante est vide ou non */
  /* Si c 'est vide elle sera la case position si non on recommence */
  /* L espace etant connexe on a necessairement une case vide voisine directe de la case pied */


  while(bool)
    {
      i=rand()%j;
      if(getCube(laby->esp,&tab[i])==0)
	{
	  remplaceVecteur(&position, &tab[i]);
	  bool=0;
	}
      else
	{
	  remplaceVecteur(&tab[i], &tab[5]);
	  j--;
	}
    }

  /* La position etant determinee il nous reste 4 possibilites pour determiner la case regard */
  /* Ces 4 possibilites dependent de l axe sur lequel se tient le visiteur */

  direction=sensDirection(&position,&pied,n); /* Ici on a la direction du corps */
  directionVecteur(direction,&axe); /* Ici on a l axe oriente sur lequel se tient le visiteur */
  
  /* On traite les 4 possibilités suivant l'axe sur lequel se tient le visiteur */

  if(compareVecteur(&axe,&v1) || compareVecteur(&axe,&v4))
    {
      /* On est sur l axe des x */
      i=rand()%4;
      addition(&position, &tabx[i],&regard,n);
    }
  
  if(compareVecteur(&axe,&v3) || compareVecteur(&axe,&v6))
    {
      /* On est sur l axe des z */
      i=rand()%4;
      addition(&position, &tabz[i],&regard,n);
    }
  if(compareVecteur(&axe,&v2) || compareVecteur(&axe,&v5))
    {
      /* On est sur l axe des y */
      i=rand()%4;
      addition(&position, &taby[i],&regard,n);
    }

/* Initialisation du joueur */
 visiteurInit2(laby->joueur, &position, &pied, &regard);

 free(tab);
 free(tabx);
 free(taby);
 free(tabz);
}


void initJeuFichier(jeu * laby, char fichier[])
{
	vecteur v;
	char pied,regard;
	
	laby->esp=(espace*)malloc(sizeof(espace));
	laby->joueur=(visiteur*)malloc(sizeof(visiteur));
	initEspaceFichier(laby->esp,&v,&pied,&regard,fichier);
	visiteurInit(laby->joueur,&v,pied,regard,laby->esp->taille);
}

int testFin(jeu * laby)
{
	if(getCube(laby->esp,laby->joueur->caseEmplacement)==9)
	{
		return 1;
	}
	else
	{
		return 0;
	}
}

void getJoueur(jeu * laby, visiteur * joueur)
{
	vecteur v;
	
	getCaseRegard(laby->joueur,&v);
	setCaseRegard(joueur,&v);
	
	getCasePied(laby->joueur,&v);
	setCasePied(joueur,&v);
	
	getCaseEmplacement(laby->joueur,&v);
	setCaseEmplacement(joueur,&v);
	
}

void getEspace(jeu * laby, espace * esp)
{
	esp->terrain=laby->esp->terrain;
	esp->taille=laby->esp->taille;
}

void Jouer(jeu * laby, char action)
{
  switch(action)
    {
    case 'd' :  visiteurChangeDirection(laby->joueur, laby->esp, 'd');
      break;
    case 'g' :  visiteurChangeDirection(laby->joueur, laby->esp, 'g');
      break;
    case 'b' :  visiteurChangeDirection(laby->joueur, laby->esp, 'b');
      break;
    case 'a' : visiteurAvance(laby->joueur, laby->esp); 
      break;
    }
}

void freeJeu(jeu* laby)
{
  freeEspace(laby->esp);
  freeVisiteur(laby->joueur);
}


